package com.azt.provider.impl;

import com.azt.api.pojo.*;
import com.azt.api.service.*;
import com.azt.model.page.Pagination;
import com.azt.provider.mapper.GiftInfoMapper;
import com.azt.provider.mapper.IntegralRecordMapper;
import com.azt.provider.mapper.IntegralRuleMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xiaoleilu.hutool.convert.Convert;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class IntegralServiceImpl implements IntegralService {

	private static Logger log = LoggerFactory.getLogger(IntegralServiceImpl.class);

	@Autowired
	private IntegralRecordMapper integralRecordMapper;

	@Autowired
	private IntegralRuleMapper integralRuleMapper;

	@Autowired
	private PrizeSetService prizeSetService;

	@Autowired
	private PrizeRecordService prizeRecordService;

	@Autowired
	private UserService userService;
	
	@Autowired
	private GiftService giftService;
	
	@Autowired
	private GiftInfoMapper giftInfoMapper;

	@Autowired
	private MsgConfigService msgConfigService;

	@Override
	public Pagination selectIntegralList(int pageno, int pagesize, Map<String, String> params) {
		Page<Object> startPage = PageHelper.startPage(pageno, pagesize);
		List<IntegralRecord> recordList = integralRecordMapper.selectMainRecord(params);
		Pagination p = new Pagination(startPage, recordList);
		p.setList(recordList);
		p.setParams(params);
		return p;
	}

	@Override
	public Pagination selectIntegralRuleList(int pageno, int pagesize, Map<String, String> params) {
		Page<Object> startPage = PageHelper.startPage(pageno, pagesize);
		List<IntegralRule> recordruleList = integralRuleMapper.selectMainRecordRule(params);
		Pagination p = new Pagination(startPage, recordruleList);
		p.setList(recordruleList);
		p.setParams(params);
		return p;
	}

	@Override
	public IntegralRule queryRuleById(Integer id) {
		return integralRuleMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<IntegralRule> findChildRule(String ruleCode) {
		if(StrUtil.isNotBlank(ruleCode)) {
			IntegralRule parent = getIngralRuleByCode(ruleCode);
			if(parent != null) {
				IntegralRule rule = new IntegralRule();
				rule.setPid(parent.getId());
				rule.setRemoved(0);
				return integralRuleMapper.select(rule);
			}
		}
		return null;
	}

	@Override
	public IntegralRule getIngralRuleByCode(String ruleCode) {
		IntegralRule itr = new IntegralRule();
		itr.setRuleCode(ruleCode);
		itr.setRemoved(0);
		return integralRuleMapper.selectOne(itr);
	}

	@Override
	public void addIngralRule(IntegralRule rule) {
		integralRuleMapper.insertSelective(rule);
	}

	@Override
	public void editIngralRule(IntegralRule rule) {
		integralRuleMapper.updateByPrimaryKeySelective(rule);
	}

	@Override
	public boolean deleteIngralRule(String ruleCode) {
		IntegralRecord ir=new IntegralRecord();
		ir.setRuleCode(ruleCode);
		List<IntegralRecord> records=integralRecordMapper.select(ir);
		boolean isub=true;
		if(records.size()>0){
			isub = false;
		}else{
			if(StringUtils.isNotBlank(ruleCode)){
				IntegralRule r=new IntegralRule();
				r.setRuleCode(ruleCode);
				integralRuleMapper.delete(r);
			}else{
				isub = false;
			}
		}
		return isub;
	}

	@Override
	public void addUserRecord(Integer userId, String ruleCode, Double amount, String desr, Integer operateId) {
		try {
			if (ruleCode != null) {
				IntegralRule rule = new IntegralRule();
				rule.setRuleCode(ruleCode);
				rule.setRemoved(0);
				IntegralRule r2 = integralRuleMapper.selectOne(rule);
				if (r2 != null) {
					IntegralRecord ir = new IntegralRecord();
					ir.setUserId(userId);
					ir.setRuleCode(ruleCode);
					ir.setRuleTitle(r2.getTitle());
					ir.setOverdue(IntegralRecord.OVERDUE);
					ir.setRuleDescr((desr == null ? "" : desr) +r2.getTitle());
					// 根据类型还是比例
					if (r2.getType().equals(1)) {
						ir.setScore(r2.getScore());
					} else if (r2.getType().equals(2)) {
						// 目前没有按比例的功能开发，如果按比例需求以下需更改 2017.2.17
					}
					else if (r2.getType().equals(3)) {
						//兑换奖品
						ir.setScore(amount);
					}
					ir.setOperateType(r2.getOperateType());
					ir.setOperateid(operateId);
					integralRecordMapper.insert(ir);
				} else {
					log.error("规则代码:{}不存在！", ruleCode);
				}
			} else {
				log.error("参数错误，ruleCode为空！");
			}
		} catch (Exception e) {
			log.error("find error", e);
		}
	}

	@Override
	public Map<String, Object> drawIngral(User user) {
		Map<String, Object> deawMap = new HashMap<String, Object>();
		// 抽奖code
		String code = "integral.shop#prize";
		UserAccount userAccount = userService.getUserAccountByUserId(user.getId());
			try {
				if (userAccount != null) {
					Integer usIntegral = userAccount.getUsIntegral();// 用户可用的积分
					IntegralRule ingralRule = this.getIngralRuleByCode(code);
					if (ingralRule != null) {
						Double ingralRuleScore = ingralRule.getScore();// 抽奖需要的积分
						if (ingralRuleScore == null) {
							// 抽奖积分为空，数据错误！
							deawMap.put("result", 3);
							log.error("抽奖需要积分为空，后台配置错误！");
							return deawMap;
						}

						// 判断积分是否够抽奖
						if (usIntegral > 0 && (usIntegral - ingralRuleScore) >= 0) {
							// 每次先扣除积分
							this.addUserRecord(user.getId(), code, null, null, null);
							PrizeSet luckyDraw = prizeSetService.luckyDraw(user);
							// 减库存
							int result = prizeSetService.updateDecrement(luckyDraw.getId());
							// 抽中奖品，且有库存，才是中奖
							if (luckyDraw != null && result > 0) {
								PrizeRecord prizeRecord = new PrizeRecord();
								prizeRecord.setUserId(user.getId());
								prizeRecord.setUseScore(ingralRuleScore.intValue());
								prizeRecord.setPrizeId(luckyDraw.getId());
								if (luckyDraw.getType() == 3) {// 抽奖送积分
									prizeRecord.setState(luckyDraw.getType());
									this.addUserRecord(user.getId(), "prize_get" , luckyDraw.getGiftPrice(), null,
											null);
								}
								prizeRecordService.SaveOrUpdateRecord(prizeRecord);
								deawMap.put("prizeRecord", prizeRecord);
								deawMap.put("recordId", prizeRecord.getId());
								deawMap.put("result", 1);// 中奖了
								deawMap.put("prizeSet", luckyDraw);
								deawMap.put("prizeId", luckyDraw.getId());
							} else {
								// 未中奖,谢谢参与
								deawMap.put("result", 0);
							}
						} else {
							// 积分不够使用
							deawMap.put("result", 2);
						}
					} else {
						log.error("获取扣除抽取积分错误，没有抽奖积分代码！");
					}

				} else {
					log.error("获取积分账户错误！");
				}
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		return deawMap;
	}

	@Override
	public List<IntegralRecord> getIntegralRecordByUserId(Integer userId) {
		IntegralRecord ird = new IntegralRecord();
		ird.setUserId(userId);
		return integralRecordMapper.select(ird);
	}

	@Override
	public List<IntegralRecord> getIntegralRecordByUserId(Integer userId, Integer operateType, Integer overdue,
			String recordTime) {
		return integralRecordMapper.getIntegralRecordByUserId(userId, operateType, overdue, recordTime);
	}

	@Override
	public Integer getOverIntegralRecordByUserId(Integer userId, Integer operateType, 
			Integer lastYear) {
		return integralRecordMapper.getOverIntegralRecordByUserId(userId, operateType, lastYear);
	}
	
	@Override
	public Integer getSinceIntegralRecordByUserId(Integer userId, Integer operateType, Integer overdue,
			String recordTime) {
		return integralRecordMapper.getSinceIntegralRecordByUserId(userId,operateType,overdue,recordTime);
	}

	@Override
	public boolean setOverdueToIntegralRecord(Integer userId, Integer operateType, Integer overdue, String recordTime) {
		try {
			integralRecordMapper.setOverdueToIntegralRecord(userId, operateType, overdue, recordTime);
			return true;
		} catch (Exception e) {
			log.error("处理用户{}过期积分出错！", userId);
			return false;
		}

	}


	@Override
	public void saveOrUpdate(IntegralRecord ir) {
		if(ir.getId()!=null){
			integralRecordMapper.insertSelective(ir);
		}else{
			integralRecordMapper.updateByPrimaryKeySelective(ir);
		}
	}
	
	 /**
     * 替换消息内容
     * @param content
     * @param params
     * @return
     */
    public String replaceContent(String content , Map<String, Object> params){
        if(StrUtil.isNotBlank(content)){
            for (String s : params.keySet()) {
                String reg = "{"+s+"}";
                if(content.contains(reg) && params.get(s) != null) {
                    content = content.replace(reg , params.get(s).toString());
                }
            }
            return content;
        }
        return "";
    }

	@Override
	public String getRuleContent(String code, int userId, Map extraParam) {
		try {
			Map param = new HashMap();
			if(CollectionUtil.isNotEmpty(extraParam)) {
				param.putAll(extraParam);
			}
			String template = "";
			if(StrUtil.isNotBlank(code)) {
				IntegralRule rule = getIngralRuleByCode(code);
				if(rule != null) {
					param.put("score", rule.getScore().intValue());
					GiftInfo gift = giftInfoMapper.selectCanExchangeMax(userId);
					if (gift != null) {
						//取达到的模板
						template = rule.getHasTemplate();
					} else {
						GiftInfo g = giftInfoMapper.selectCanNotExchangeMin(userId);
						if (g != null) {
							UserAccount ua = userService.getUserAccountByUserId(userId);

							int count = g.getIntegralNum().intValue() - (ua != null ? ua.getUsIntegral().intValue() : 0);
							Integer size = Convert.toInt(rule.getScore());

							Integer times = count % size == 0 ? count / size : count / size + 1;

							param.put("times", times.toString());

							//取未达到的模板
							template = rule.getDisTemplate();
						}
					}
					if(StrUtil.isNotBlank(template)) {
						return replaceContent(template, param);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("error", e);
		}
		return "";
	}

	@Override
	public List<IntegralRule> selectIntegralRuleList() {
		List<IntegralRule> integralRule=integralRuleMapper.selectAll();
		return integralRule;
	}

	@Override
	public List<IntegralRecord> getIntegralRecordInstruct() {
		return integralRuleMapper.getIntegralRecordInstruct();
	}
	
	@Override
	public Integer selectSignRecord(Integer userId,String code){
		return integralRecordMapper.selectSignRecord(userId,code);
	}
	
	@Override
	public  String exchageGift(User user, GiftExchange ge) {
		String msg = "";
		try {
			UserAccount userAccount = userService.getUserAccountByUserId(user.getId());
			GiftInfo gi = giftService.getGiftInfoById(ge.getGiftId());
			Integer usIntegral = userAccount != null? userAccount.getUsIntegral():0;
			Double allAmount = ge.getExchangeAmount() * gi.getIntegralNum().doubleValue();
			ge.setUserId(user.getId());
			ge.setExchangetime(new Date());
			
			if (gi.getStockAmount() >= ge.getExchangeAmount()) {//库存是否足够
				if (usIntegral >= allAmount) {//积分是否充足
					try {
						// 扣除积分
						this.addUserRecord(user.getId(), "prize_exchange", allAmount, null, null);
						// 礼品兑换
						giftService.addGiftExchange(ge);
						// 减少库存
						giftService.updateGiftStock(ge);
						msg = "兑换成功";
						Map<String, String> params = new HashMap<String, String>();
						params.put("user", StrUtil.isNotBlank(user.getMobile()) ? user.getMobile() : user.getEmail());
						params.put("gift", gi.getGiftName());
						msgConfigService.sendMessage("AUDIT_GIFT" , params , null , new ArrayList());//通知运营人员
					} catch (Exception e) {
						log.error("submit giftexchange  error", e);
						msg = "兑换失败";
					}
				} else {
					msg = "积分不足";
				}
			} else {
				msg = "库存不足";
			}
		} catch (Exception e) {
			log.error("parse giftexchange request data error", e);
			msg = "兑换失败";
		}
		return msg;
	}

}
